package practice;

class A0{
    static{
        System.out.println("A0 static");
    }
    public A0() {
        System.out.println("A0()");
    }
}

class A00{
    static{
        System.out.println("A00 static");
    }
    public A00() {
        System.out.println("A00()");
    }
}

class A1{
    private A00 a00 = new A00();

    static{
        System.out.println("A1 static");
    }
    public A1() {
        System.out.println("A1()");
    }
}

class A2 extends A1{
    B2 b2 = new B2();
    private static A0 a0 = new A0();

    static{
        System.out.println("A2 static");
    }
    public A2() {
        System.out.println("A2()");
    }
}
class B2{
    C2 c2 = new C2();
    D2 d2 = new D2();
    static{
        System.out.println("B static");
    }
    public B2() {
        System.out.println("B2()");
    }
}
class C2{
    static{
        System.out.println("C static");
    }
    public C2() {
        System.out.println("C2()");
    }
}
class D2{
    static{
        System.out.println("D static");
    }
    public D2() {
        System.out.println("D2()");
    }
}

/**
 * 类加载顺序：
 * 第一点，所有的类都会优先加载基类
 * 第二点，静态成员的初始化优先
 * 第三点，成员初始化后，才会执行构造方法
 * 第四点，静态成员的初始化与静态块的执行，发生在类加载的时候。
 * 第四点，类对象的创建以及静态块的访问，都会触发类的加载。
 *
 * 类构造方法的顺序:
 *  首先会调用基类的构造方法
 *  其次，调用成员的构造方法
 *  最后，调用自己的构造方法
 *
 *
 * 父类静态变量->父类静态块->子类静态变量->子类静态块 ->父类变量 -> 父类构造方法-> 子类变量 -> 子类构造方法
 */
public class JVMLoad {
    public static void main(String[] args) {
        A2 a2 = new A2();
    }
}